<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META NAME="GENERATOR" CONTENT="Mozilla/4.5b2 [en] (X11; I; Linux 2.0.34 i686) [Netscape]">
   <TITLE>Simple Vector Library (documentation)</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
&nbsp;
<CENTER><TABLE BORDER=0 COLS=1 WIDTH="60%" HEIGHT="60" BGCOLOR="#FFFFCC" NOSAVE >
<TR ALIGN=CENTER NOSAVE>
<TD NOSAVE><B><FONT SIZE=+4><A HREF="index.html">Simple Vector Library</A></FONT></B></TD>
</TR>
</TABLE></CENTER>

<TABLE BORDER=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC00" NOSAVE >
<TR>
<TD><A NAME="index"></A><B><FONT SIZE=+3><A HREF="#index">Contents</A></FONT></B></TD>
</TR>
</TABLE>

<UL>
<LI>
<A HREF="#description">Description</A></LI>

<LI>
<A HREF="#classes">Classes</A></LI>

<LI>
<A HREF="#indexing">Element Access</A></LI>

<LI>
<A HREF="#operators">Arithmetic Operators and Functions</A></LI>

<LI>
<A HREF="#constants">Constants</A></LI>

<LI>
<A HREF="#constructors">Constructors</A></LI>

<LI>
<A HREF="#io">Input and Output</A></LI>

<LI>
<A HREF="#xforms">Transformations</A></LI>

<LI>
<A HREF="#compiling">Compiling with SVL</A></LI>

<LI>
<A HREF="#opengl">Using SVL With OpenGL</A></LI>

<LI>
<A HREF="#author">Author</A></LI>
</UL>

<TABLE BORDER=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC00" NOSAVE >
<TR VALIGN=CENTER NOSAVE>
<TD NOSAVE><A NAME="description"></A><B><FONT SIZE=+3><A HREF="#index">Description</A></FONT></B></TD>
</TR>
</TABLE>

<P>The Simple Vector Library (SVL) provides vector and matrix classes,
as well as a number of functions for performing vector arithmetic with
them. Equation-like syntax is supported via class operators, for example:
<PRE>&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; #include "SVL.h"
&nbsp;&nbsp;&nbsp; Vec3&nbsp;&nbsp;&nbsp; v(1.0, 2.0, 3.0);
&nbsp;&nbsp;&nbsp; Mat3&nbsp;&nbsp;&nbsp; m(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);

&nbsp;&nbsp;&nbsp; v =&nbsp; 2 * v + m * v;
&nbsp;&nbsp;&nbsp; v *= (m / 3.0) * norm(v);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; cout &lt;&lt; v &lt;&lt; endl;</PRE>
Both generic (arbitrarily-sized), and fixed-size (2, 3 and 4 element) vectors
and matrices are supported. The latter are provided for the efficient manipulation
of vectors or points in 2D or 3D space, and make heavy use of inlining
for frequently-used operations. (One of the design goals of SVL was to
ensure that it was as fast as the C-language, macro-based libraries it
was written to replace.)
<P>SVL is a subset of VL, a more extensive vector library, which in addition
contains classes for sparse vector/matrices, sub-vector/matrices, and implementations
of some iterative solvers. Whereas with SVL the component type of vectors
and matrices is defined with a compile-time switch, with VL you specify
the type explicitly (Vec2f, Vec2d) and can, for example, mix matrices of
doubles with vectors of floats.
<P>SVL requires C++. It is known to compile under CC/DCC (Irix), g++, and
Metrowerks C++. The latest version can be retrieved from <A HREF="http://www.cs.cmu.edu/~ajw/public/dist/svl.tar.gz">http://www.cs.cmu.edu/~ajw/public/dist/svl.tar.gz</A>.
This documentation can be found online at <A HREF="http://www.cs.cmu.edu/~ajw/doc/svl.html">http://www.cs.cmu.edu/~ajw/doc/svl.html</A>.
<BR>&nbsp;
<BR>&nbsp;
<TABLE BORDER=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC00" NOSAVE >
<TR VALIGN=CENTER NOSAVE>
<TD NOSAVE><A NAME="classes"></A><B><FONT SIZE=+3><A HREF="#index">Classes</A></FONT></B></TD>
</TR>
</TABLE>

<P>SVL contains the following types and classes:
<PRE>&nbsp;&nbsp;&nbsp; Fixed-size:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Real&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; component type (float or double)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Vec2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2-vector
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Vec3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3-vector
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Vec4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4-vector
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mat2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 x 2 matrix
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mat3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3 x 3 matrix
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mat4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4 x 4 matrix
&nbsp;&nbsp;&nbsp; Generic:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Vec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n-vector
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n x m matrix</PRE>
&nbsp;
<TABLE BORDER=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC00" NOSAVE >
<TR VALIGN=CENTER NOSAVE>
<TD NOSAVE><A NAME="indexing"></A><B><FONT SIZE=+3><A HREF="#index">Element
Access</A></FONT></B></TD>
</TR>
</TABLE>

<P>The elements of a vector or matrix are accessed with standard C array
notation:
<PRE>&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; v[2] = 4.0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // set element 2 of the vector
&nbsp;&nbsp;&nbsp; m[3][4] = 5.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // set row 3, column 4 of the matrix
&nbsp;&nbsp;&nbsp; m[2] = v;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // set row 2 of the matrix</PRE>
Though it seems slightly unintuitive, if you have a pointer to a vector
or matrix, you must dereference it first before indexing it:
<PRE>&nbsp;&nbsp;&nbsp; (*vPtr)[20] = 3.0;</PRE>
If you need a pointer to the data belonging to a vector or matrix, use
the Ref() method. (Matrices are stored by row.)
<PRE>&nbsp;&nbsp;&nbsp; Real *vecDataPtr = v.Ref(), *matDataPtr = m.Ref();</PRE>
<B>Warning</B>: Any pointer to a generic matrix or vector will become invalid
as soon as it is resized.
<P><B>Note</B>: If you compile with -DVL_CHECKING, index range checks will
be performed on all element accesses.
<BR>&nbsp;
<BR>&nbsp;
<TABLE BORDER=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC00" NOSAVE >
<TR VALIGN=CENTER NOSAVE>
<TD NOSAVE><A NAME="operators"></A><B><FONT SIZE=+3><A HREF="#index">Arithmetic
Operators and Functions</A></FONT></B></TD>
</TR>
</TABLE>

<H3>
Arithmetic Operators</H3>
The following binary operators are defined for all vector and matrix classes,
as long as both operands are of the same type.
<PRE>&nbsp;&nbsp;&nbsp; Basic arithmetic:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + - * /
&nbsp;&nbsp;&nbsp; Accumulation arithmetic:&nbsp; += -= *= /=
&nbsp;&nbsp;&nbsp; Comparison:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ==, !=</PRE>
Vector multiplication and division is pairwise: (a * b)[i] = a[i] * b[i].
(See below for how to form the dot product of two vectors with dot().)
Matrix multiplication is defined as usual, and matrix division is undefined.
<P>For both matrices and vectors, multiplication and division by a scalar
is also allowed. Matrices can be multiplied either on the left or the right
by a vector. In the expression m * v, v is treated as a column vector;
in the expression v * m, it is treated as a row vector.
<H3>
Vector Functions</H3>
The following is a list of the various vector functions, together with
a short description of what they return.
<PRE>&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; Real dot(const VecN &amp;a, const VecN &amp;b);&nbsp;&nbsp;&nbsp;&nbsp; // inner product of a and b
&nbsp;&nbsp;&nbsp; Real len(const VecN &amp;v);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // length of v: || v ||
&nbsp;&nbsp;&nbsp; Real sqrlen(const VecN &amp;v);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // length of v, squared
&nbsp;&nbsp;&nbsp; VecN norm(const VecN &amp;v);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // v / || v ||

&nbsp;&nbsp;&nbsp; Vec2 cross(const Vec2 &amp;a);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // vector orthogonal to a&nbsp;
&nbsp;&nbsp;&nbsp; Vec3 cross(const Vec3 &amp;a, const Vec3 &amp;b);&nbsp;&nbsp; // vector orthogonal to a and b
&nbsp;&nbsp;&nbsp; Vec4 cross(const Vec4 &amp;a, const Vec4 &amp;b, const Vec4 &amp;c);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // vector orthogonal to a, b and c

&nbsp;&nbsp;&nbsp; Vec2 proj(const Vec3 &amp;v);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // homog. projection: v[0..1] / v[2]
&nbsp;&nbsp;&nbsp; Vec3 proj(const Vec4 &amp;v);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // homog. projection: v[0..2] / v[3]</PRE>
For more on the use of the proj() operator, see <A HREF="#xforms">Transformations</A>.
<H3>
Matrix Functions</H3>
The following functions can be used with matrices.
<PRE>&nbsp;&nbsp;&nbsp; MatN trans(const MatN &amp;m);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Transpose of m&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; Real trace(const MatN &amp;m);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Trace of m
&nbsp;&nbsp;&nbsp; MatN adj(const MatN &amp;m);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Adjoint of m
&nbsp;&nbsp;&nbsp; Real det(const MatN &amp;m);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Determinant of m
&nbsp;&nbsp;&nbsp; MatN inv(const MatN &amp;m);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Inverse of m, if it exists.</PRE>
The det() and adj() functions are only defined for Mat[234].
<BR>&nbsp;
<BR>&nbsp;
<TABLE BORDER=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC00" NOSAVE >
<TR VALIGN=CENTER NOSAVE>
<TD NOSAVE><A NAME="constants"></A><B><FONT SIZE=+3><A HREF="#index">Constants</A></FONT></B></TD>
</TR>
</TABLE>

<P>There are a number of 'magic' constants in VL that can be used to initialise
vectors or matrices with simple assignment statements. For example:
<PRE>&nbsp;&nbsp;&nbsp; Vec3 v; Mat3 m; Vec v8(8);

&nbsp;&nbsp;&nbsp; v = vl_0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [0, 0, 0]
&nbsp;&nbsp;&nbsp; v = vl_y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [0, 1, 0]
&nbsp;&nbsp;&nbsp; v = vl_1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [1, 1, 1]
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; m = vl_0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3 x 3 matrix, all elts. set to zero.
&nbsp;&nbsp;&nbsp; m = vl_1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3 x 3 identity matrix
&nbsp;&nbsp;&nbsp; m = vl_B;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3 x 3 matrix, all elts. set to one.
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; v8 = vl_axis(6);&nbsp;&nbsp;&nbsp; [0, 0, 0, 0, 0, 0, 1, 0]</PRE>
Below is a summary of the constants defined by SVL.
<PRE>&nbsp;&nbsp;&nbsp; vl_one/vl_1/vl_I&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector of all 1s, or identity matrix
&nbsp;&nbsp;&nbsp; vl_zero/vl_0/vl_Z&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector or matrix of all 0s
&nbsp;&nbsp;&nbsp; vl_B&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; matrix of all 1s
&nbsp;&nbsp;&nbsp; vl_x, vl_y, vl_z, vl_w&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x, y, z and w axis vectors
&nbsp;&nbsp;&nbsp; vl_axis(n)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; zero vector with element n set to 1
&nbsp;&nbsp;&nbsp; vl_pi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pi!
&nbsp;&nbsp;&nbsp; vl_halfPi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pi/2</PRE>
&nbsp;
<TABLE BORDER=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC00" NOSAVE >
<TR VALIGN=CENTER NOSAVE>
<TD NOSAVE><A NAME="constructors"></A><B><FONT SIZE=+3><A HREF="#index">Constructors</A></FONT></B></TD>
</TR>
</TABLE>

<P>In general, a vector or matrix constructor should be given either one
of the initialiser constants listed above, or a list of values for its
elements. If neither of these is supplied, the variable will be uninitialised.
The first arguments to the constructor of a generic vector or matrix should
always be the required size. Thus matrices and vectors are declared as
follows:
<PRE>&nbsp;&nbsp;&nbsp; Vec[234]&nbsp;&nbsp;&nbsp; v([initialisation_constant | element_list]);
&nbsp;&nbsp;&nbsp; Vec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; v([elements, [initialisation_constant | element_list]]);
&nbsp;&nbsp;&nbsp; Mat[234]&nbsp;&nbsp;&nbsp; m([initialisation_constant | element_list]);
&nbsp;&nbsp;&nbsp; Mat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m([rows, columns, [initialisation_constant | element_list]]);</PRE>
If generic vectors or matrices are not given a size when first created,
they are regarded as empty, with no associated storage. This state persists
until they are assigned a matrix/vector or the result of some computation,
at which point they take on the dimensions of that result.
<P>Examples:
<PRE>&nbsp;&nbsp;&nbsp; Vec3&nbsp;&nbsp;&nbsp; v(vl_1);
&nbsp;&nbsp;&nbsp; Vec3&nbsp;&nbsp;&nbsp; v(1.0, 2.0, 3.0);
&nbsp;&nbsp;&nbsp; Vec&nbsp;&nbsp;&nbsp;&nbsp; v(6, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0);&nbsp;
&nbsp;&nbsp;&nbsp; Vec&nbsp;&nbsp;&nbsp;&nbsp; v(20, vl_axis(10));
&nbsp;&nbsp;&nbsp; Mat2&nbsp;&nbsp;&nbsp; m(1.0, 2.0, 3.0, 4.0);
&nbsp;&nbsp;&nbsp; Mat&nbsp;&nbsp;&nbsp;&nbsp; m(10, 20, vl_I);</PRE>
<B>Warning</B>: When initialising a generic vector or matrix with a list
of elements, you must always ensure there is no possibility of the element
being mistaken for an integer. (This is due to limitations of the stdarg
package.) Make sure that each element value has either an exponent or a
decimal point, i.e., use '2.0' rather than just '2'.
<P>Finally, to set the size of a empty matrix or vector explicitly, or
resize an existing matrix or vector, use the SetSize method:
<PRE>&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; v.SetSize(23);
&nbsp;&nbsp;&nbsp; m.SetSize(10, 20);</PRE>
&nbsp;
<TABLE BORDER=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC00" NOSAVE >
<TR VALIGN=CENTER NOSAVE>
<TD NOSAVE><A NAME="io"></A><B><FONT SIZE=+3><A HREF="#index">Input and
Output</A></FONT></B></TD>
</TR>
</TABLE>

<P>All of the vector and matrix types in SVL can be used in iostream-type
expressions. For example:
<PRE>&nbsp;&nbsp;&nbsp; #include &lt;iostream.h>
&nbsp;&nbsp;&nbsp; Vec3 v(vl_1);
&nbsp;&nbsp;&nbsp; cout &lt;&lt; v &lt;&lt; 2 * v &lt;&lt; endl;
&nbsp;&nbsp;&nbsp; cin >> v;</PRE>
will output
<PRE>&nbsp;&nbsp;&nbsp; [1 1 1][2 2 2]</PRE>
and then prompt for input. Vectors and matrices are parsed in the same
format that they are output: vectors are delimited by square brackets,
elements separated by white space, and matrices consist of a series of
row vectors, again delimited by square brackets.
<BR>&nbsp;
<BR>&nbsp;
<TABLE BORDER=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC00" NOSAVE >
<TR VALIGN=CENTER NOSAVE>
<TD NOSAVE><A NAME="xforms"></A><B><FONT SIZE=+3><A HREF="#index">Transformations</A></FONT></B></TD>
</TR>
</TABLE>

<P>The following are the transformations supported by SVL.
<PRE>&nbsp;&nbsp;&nbsp; Mat2&nbsp;&nbsp;&nbsp; Rot2(Real theta)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // rotate a 2d vector CCW by theta
&nbsp;&nbsp;&nbsp; Mat2&nbsp;&nbsp;&nbsp; Scale2(const Mat2 &amp;s)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // scale by s around the origin
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; Mat3&nbsp;&nbsp;&nbsp; HRot3(Real theta)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // rotate a homogeneous 2d vector CCW by theta
&nbsp;&nbsp;&nbsp; Mat3&nbsp;&nbsp;&nbsp; HScale3(const Mat2 &amp;s)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // scale by s around the origin, in homogeneous 2d coords.
&nbsp;&nbsp;&nbsp; Mat3&nbsp;&nbsp;&nbsp; HTrans3(const Mat2 &amp;t)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // translate a homogeneous 2d vector by t

&nbsp;&nbsp;&nbsp; Mat3&nbsp;&nbsp;&nbsp; Rot3(const Mat3 &amp;axis, Real theta)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // rotate a 3d vector CCW around axis by theta
&nbsp;&nbsp;&nbsp; Mat3&nbsp;&nbsp;&nbsp; Rot3(const Mat4 &amp;q)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // rotate a 3d vector by the quaternion q
&nbsp;&nbsp;&nbsp; Mat3&nbsp;&nbsp;&nbsp; Scale3(const Vec3 &amp;s)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // scale by s around the origin

&nbsp;&nbsp;&nbsp; Mat4&nbsp;&nbsp;&nbsp; HRot4(const Mat3 &amp;axis, Real theta)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // rotate a homogeneous 3d vector CCW around axis by theta
&nbsp;&nbsp;&nbsp; Mat4&nbsp;&nbsp;&nbsp; HRot4(const Mat4 &amp;q)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // rotate a homogeneous 3d vector by the quaternion q
&nbsp;&nbsp;&nbsp; Mat4&nbsp;&nbsp;&nbsp; HScale4(const Mat3 &amp;s)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // scale by s around the origin, in homogeneous 3d coords
&nbsp;&nbsp;&nbsp; Mat4&nbsp;&nbsp;&nbsp; HTrans4(const Mat3 &amp;t)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // translate a homogeneous 3d vector by t</PRE>
Transformations with a prefix of 'H' operate in the homogeneous coordinate
system, which allows translation and shear transformations, as well as
the usual rotation and scale. In this coordinate system an n-vector is
embedded in a (n+1)-dimensional space, e.g., a homogeneous point in 2d
is represented by a 3-vector.
<P>To convert from non-homogeneous to homogeneous vectors, make the extra
coordinate (usually 1) the second argument in a constructor of/cast to
the next-higher dimension vector. To project from a homogeneous vector
down to a non-homogeneous one (doing a homogeneous divide in the process),
use the proj() function. This process can be simplified by the use of the
xform() function, which applies a transform to a vector, doing homogeneous/nonhomogeneous
conversions if necessary. For example:
<PRE>&nbsp;&nbsp;&nbsp; Vec3 x,y;

&nbsp;&nbsp;&nbsp; // apply homogeneous transformations to a 3-vector&nbsp;
&nbsp;&nbsp;&nbsp; x = proj(Scale4(...) * Rot4(...) * Trans4(...) * Vec4(y, 1.0));
&nbsp;&nbsp;&nbsp; // do the same thing with xform()
&nbsp;&nbsp;&nbsp; x = xform(Scale4(...) * Rot4(...) * Trans4(...), y);</PRE>
By default, SVL assumes that transformations should operate on column vectors
(v = T * v), though it can be compiled to assume row vectors instead (v
= v * T).
<BR>&nbsp;
<BR>&nbsp;
<TABLE BORDER=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC00" NOSAVE >
<TR VALIGN=CENTER NOSAVE>
<TD NOSAVE><A NAME="compiling"></A><B><FONT SIZE=+3><A HREF="#index">Compiling
with SVL</A></FONT></B></TD>
</TR>
</TABLE>

<H3>
Headers</H3>
For basic use, the only header file needed is SVL.h.
<H3>
Linking</H3>
For your final build, link with -lsvl (libsvl.a). To use the debugging
version of SVL, which has assertions and range checking turned on, use
-lsvl.dbg (libsvl.dbg.a). This debugging version includes checks for correct
matrix and vector sizes during arithmetic operations.
<H3>
Compile options</H3>
SVL uses the following compile-time options:
<PRE>&nbsp;&nbsp;&nbsp; VL_FLOAT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - use floats instead of doubles
&nbsp;&nbsp;&nbsp; VL_CHECKING&nbsp;&nbsp;&nbsp;&nbsp; - turn on index checking and assertions
&nbsp;&nbsp;&nbsp; VL_ROW_ORIENT&nbsp;&nbsp; - transformations operate on row vectors instead of column vectors</PRE>
&nbsp;
<TABLE BORDER=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC00" NOSAVE >
<TR VALIGN=CENTER NOSAVE>
<TD NOSAVE><A NAME="opengl"></A><B><FONT SIZE=+3><A HREF="#index">Using
SVL With OpenGL</A></FONT></B></TD>
</TR>
</TABLE>

<P>SVL comes with a header file, SVLgl.h, which makes using SVL vectors
with OpenGL more convenient. For example:
<PRE>&nbsp;&nbsp;&nbsp; #include "SVLgl.h"
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; Vec3 x(24, 0, 100), y(40, 20, 10);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; glBegin(GL_LINES);
&nbsp;&nbsp;&nbsp; glVertex(x);&nbsp;
&nbsp;&nbsp;&nbsp; glVertex(y);
&nbsp;&nbsp;&nbsp; glEnd();</PRE>
&nbsp;
<TABLE BORDER=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC00" NOSAVE >
<TR VALIGN=CENTER NOSAVE>
<TD NOSAVE><A NAME="author"></A><B><FONT SIZE=+3><A HREF="#index">Author</A></FONT></B></TD>
</TR>
</TABLE>

<P>Please forward bug reports, comments, or suggestions to:
<ADDRESS>
Andrew Willmott (<A HREF="mailto:ajw+vl@cs.cmu.edu">ajw+vl@cs.cmu.edu</A>),
Graphics Group, SCS, CMU.</ADDRESS>

</BODY>
</HTML>
